<template>
	<el-row :gutter="40">
		<el-col v-if="!form.id">
			<el-empty description="请选择左侧菜单后操作" :image-size="100"></el-empty>
		</el-col>

		<template v-else>
			<el-col :lg="12">
				<h2>{{ form.title || "新增菜单" }}</h2>
				<el-form ref="dialogForm" :model="form" :rules="rules" label-width="80px" label-position="right">
					<el-form-item label="显示标题" prop="title"
					              :rules="{ required: true, message: '请输入菜单显示标题' }">
						<el-input v-model="form.title" clearable placeholder="菜单显示标题" :maxlength="6"></el-input>
					</el-form-item>
					<el-form-item label="上级菜单" prop="parent_id">
						<el-input :value="parentMenuName" disabled></el-input>
					</el-form-item>
					<el-form-item label="类型" prop="type">
						<el-radio-group v-model="form.type">
							<el-radio-button
								v-for="type in filter.type"
								:key="type.key"
								:value="type.key"
							>{{ type.label }}
							</el-radio-button>
						</el-radio-group>
					</el-form-item>
					<el-form-item label="名称" prop="name" :rules="{ required: true, message: '请输入菜单名称' }">
						<el-input v-model="form.name" clearable placeholder="菜单名称"></el-input>
						<div class="el-form-item-msg">系统唯一且与内置组件名一致，否则导致缓存失效</div>
					</el-form-item>
					<el-form-item label="菜单图标" prop="icon">
						<fc-icon-select v-model="form.icon" clearable></fc-icon-select>
					</el-form-item>
					<el-form-item label="路由地址" prop="path" :rules="{ required: true, message: '请输入路由地址' }">
						<el-input v-model="form.path" clearable placeholder="路由地址"></el-input>
						<div class="el-form-item-msg">外链是以http或https开头的外部连接网址</div>
					</el-form-item>
					<el-form-item label="重定向" prop="redirect">
						<el-input v-model="form.redirect" clearable placeholder="重定向的路由地址"></el-input>
					</el-form-item>
					<el-form-item label="菜单高亮" prop="active">
						<el-input v-model="form.active" clearable placeholder=""></el-input>
						<div class="el-form-item-msg">子节点或详情页需要高亮的上级菜单路由地址</div>
					</el-form-item>
					<el-form-item label="视图" prop="component">
						<el-input v-model="form.component" clearable placeholder="">
							<template #prepend>views/</template>
						</el-input>
						<div class="el-form-item-msg">如父节点、外链等没有视图的菜单不需要填写</div>
					</el-form-item>
					<el-form-item label="页面缓存" prop="is_keep_alive">
						<el-switch v-model="form.is_keep_alive" active-value="TRUE" inactive-value="FALSE"/>
						<div class="el-form-item-msg">缓存后每次切换标签页，页面内容不会重新加载</div>
					</el-form-item>
					<el-form-item label="是否隐藏" prop="is_hide">
						<el-switch v-model="form.is_hide" active-value="TRUE" inactive-value="FALSE"/>
						<div class="el-form-item-msg">菜单不显示在导航中，但用户依然可以访问，例如详情页</div>
					</el-form-item>
					<el-form-item label="整页路由" prop="is_full">
						<el-switch v-model="form.is_full" active-value="TRUE" inactive-value="FALSE"/>
					</el-form-item>
					<el-form-item label="固定标签" prop="is_affix">
						<el-switch v-model="form.is_affix" active-value="TRUE" inactive-value="FALSE"/>
					</el-form-item>
					<el-form-item label="tag标签" prop="tag">
						<el-input v-model="form.tag" clearable placeholder="最长6个字"
						          :maxlength="6"></el-input>
					</el-form-item>
					<el-form-item label="排序" prop="sort">
						<el-input-number v-model="form.sort" :min="0"/>
					</el-form-item>
					<el-form-item label="状态" prop="state">
						<el-radio-group v-model="form.state">
							<el-radio
								v-for="state in filter.state"
								:key="state.key"
								:value="state.key"
							>{{ state.label }}
							</el-radio>
						</el-radio-group>
					</el-form-item>


				</el-form>
			</el-col>
			<!-- 接口权限表格 -->
			<el-col :lg="12" class="apilist">
				<h2>接口权限</h2>
				<fc-form-table
					:data="routeList"
					:columns="columns"
					:data-template="dataTemplate"
				>
					<template #route="{ row }">
						<el-select
							v-model="row.route"
							@change="onRouteChange(row)"
							filterable
							remote
							clearable
							placeholder="请选择接口"
							:remote-method="remoteSearch"
							:loading="loading"
							style="width: 100%"
						>
							<el-option
								v-for="item in filteredRoutes"
								:key="item.route"
								:label="`${item.description} | ${item.method} | ${item.route}`"
								:value="item.route"
							/>
						</el-select>
					</template>
				</fc-form-table>
			</el-col>
			<el-col :lg="12" :xs="24" class="save-btn-col">
				<el-form-item label-width="80px">
					<el-button type="primary" v-auth="'menu.update'" @click="update" :loading="loading">保 存
					</el-button>
				</el-form-item>
			</el-col>
		</template>
	</el-row>
</template>

<script setup lang="ts">
import {ref, reactive, computed, onMounted} from "vue";
import {RequestMenuModel, RouteModel} from "@/models/settingModel.ts";
import FcFormTable, {FTColumnProps} from "@/components/fcFormTable/index.vue";
import {getMenuFilterApi, getRoutesApi, updateMenuApi} from "@/api/modules/setting.ts";
import {ElMessage} from 'element-plus';
import {FilterModel} from "@/models/filterModel.ts";

// 表格列配置
const columns = reactive<FTColumnProps<RouteModel>[]>([
	{prop: "route", label: "接口路由"}
]);
// 表格数据
const routeList = ref<RouteModel[]>([]);
// fc-form-table要求的模板
const dataTemplate = reactive<RouteModel>({
	route: "",
	method: "",
	description: ""
});
// 所有接口
const allRoutes = ref<RouteModel[]>([]);
const remoteQuery = ref("");
// 搜索过滤
const filteredRoutes = computed(() => {
	if (!remoteQuery.value) return allRoutes.value;
	return allRoutes.value.filter(r =>
		r.route.includes(remoteQuery.value) || r.description.includes(remoteQuery.value)
	);
});
const remoteSearch = (query: string) => {
	remoteQuery.value = query;
};
// 初始表单模板
const initialForm = (): RequestMenuModel => ({
	id: 0,
	parent_id: 0,
	name: "",
	path: "",
	redirect: "",
	component: "",
	title: "",
	icon: "",
	active: "",
	tag: "",
	type: "",
	is_hide: "",
	is_full: "",
	is_affix: "",
	is_keep_alive: "",
	sort: 0,
	state: "",
	permission: [],
	role: [],
});
const form = ref<RequestMenuModel>(initialForm());

const props = defineProps<{
	menu: Menu.MenuOptions[],
	updateMenuNode: (data: RequestMenuModel) => void
}>();

const rules = reactive({});
const loading = ref(false);
// 获取接口列表
const routes = async () => {
	try {
		const routeData = await getRoutesApi();
		allRoutes.value = routeData.data.data;
	} catch (e) {
		console.error(e);
	}
};

const filter = reactive<FilterModel>({
	type: [],
	state: [],
});
const filters = async () => {
	try {
		const filterData = await getMenuFilterApi();
		filter.type = Object.entries(filterData.data.data.type as Record<string, string>).map(([key, label]) => ({
			key,
			label
		}));
		filter.state = Object.entries(filterData.data.data.state as Record<string, string>).map(([key, label]) => ({
			key,
			label
		}));
		return true;
	} catch (e) {
		return false;
	}
};
const onRouteChange = (row: RouteModel) => {
	const selected = allRoutes.value.find(r => r.route === row.route);
	if (selected) {
		row.method = selected.method;
		row.description = selected.description;
	}
};
const update = async () => {
	loading.value = true;
	try {
		form.value.permission = routeList.value.filter(item => item.route !== null && item.route !== '');
		const menuData = await updateMenuApi(form.value);
		props.updateMenuNode(menuData.data.data);
		ElMessage.success(menuData.message);
	} catch (error) {
		console.error(error);
	} finally {
		loading.value = false;
	}
};

onMounted(() => {
	routes();
	filters();
});

// 计算父菜单名称
const parentMenuName = computed(() => {
	if (!form.value.parent_id || form.value.parent_id === 0) return '顶级菜单';

	const findParent = (tree: Menu.MenuOptions[], id: number): Menu.MenuOptions | undefined => {
		for (const node of tree) {
			if (node.id === id) return node;
			if (node.children) {
				const found = findParent(node.children, id);
				if (found) return found;
			}
		}
	};
	return findParent(props.menu, form.value.parent_id)?.title || '顶级菜单';
});
// 父组件可调用
const setData = (data: any, pid: number) => {
	form.value = initialForm();
	Object.assign(form.value, data, {parent_id: pid});
	routeList.value.splice(0, routeList.value.length);
	if (data.permission) {
		data.permission.forEach((p: RouteModel) => routeList.value.push({...p}));
	}
};
defineExpose({setData});
</script>

<style scoped>
h2 {
	font-size: 17px;
	color: #3c4a54;
	padding: 0 0 30px 0;
}

.apilist {
	border-left: 1px solid #eee;
	padding-left: 10px;
}

.save-btn-col {
	display: flex;
	justify-content: flex-start; /* PC 左对齐 */
	margin-top: 20px;
}

@media (max-width: 768px) {
	.save-btn-col {
		padding-left: 0; /* 手机端去掉左边距 */
		justify-content: flex-end; /* 手机端靠右 */
	}
}
</style>
